package com.gszy.auth.security;


/**
 * 用来保存每个请求的用户信息
 * 当请求进到服务器里面时 有Filter去读取HttpSession里面的用户信息 如果没有用户信息 就跳转到登录界面
 * 用户已经登录时 能够从会话对象中获取登录信息 将登录信息保存在SecurityContextHolder
 * 就能够再同一次请求中任何的地方获取登录信息 service controller
 */
public class SecurityContextHolder {

    /**
     * Threadlocal 线程的本地对象集合
     * 其内部维护了一个Map<Thead,UserDetails>
     *     在添加数据的时候 ThreadLocal会自动获取当前线程 然后将线程对象作为key和value绑定在一起
     *     只要是同一个线程之内 都可以根据当前线程获取之前绑定的数据
     *     并且这些绑定的数据一定是线程安全的
     *     由于Tomat在接受请求之后 会自动启动一个线程 所有这个Thread可以理解一个单独的请求
     *     结论 ThreadLocal 能够为每个请求保存个性化的单独i西南西
     *
     *     流程
     *     1.在请求进来的时候 单独启动一个线程 然后使用Threadlocal 在本次请求中保存用户信息
     *     2.在servicecontroler 只要是同一次请求 就能够获取之前ThreadLocal中保存的用户信息
     *
     */
    private static ThreadLocal<UserDetails> authenticationHolder = new ThreadLocal<>();
    private SecurityContextHolder(){

    }
    private static SecurityContextHolder holder = new SecurityContextHolder();
    public static SecurityContextHolder getInstance(){
        return holder;
    }
    public UserDetails getUserDetails(){

        return authenticationHolder.get();
    }
    public void removeUserDetails(){
        authenticationHolder.remove();
    }

    public void addUserDetails(UserDetails userDetails){
        authenticationHolder.set(userDetails);

    }
}
